<?php
namespace soa\partner\sto;

use artisan\http;
use soa\check\EnvCheck;

/**
 * 申通订单服务API
 *
 * 文档：
 *      http://order.sto-express.cn/Service
 *      http://base.sto-express.cn/document/SubscribeV4.6.html
 *
 * @package soa\partner\sto
 */
class StoOrder
{
    private $appKey = 'kuaibao';

    private $appSecret = 'edcbad5b48da403b94f4cfafa1f2c2b9';

    /**
     * 获取申通接口地址
     *
     * @param string $route
     * @return string
     */
    private function getApi($route = '')
    {
        $url = 'http://order.sto-express.cn:8001/api/Order/ProcessRequest';

        $isOnlineEnv = (new EnvCheck())->isEnvOnline();

        $testIpArr = ['127.0.0.1', '192.168.1.81', '121.41.38.122'];
        if (in_array( $_SERVER['SERVER_ADDR'], $testIpArr) || !$isOnlineEnv) {
            $url = 'http://order.sto-express.cn:8001/api/Order/ProcessRequestTest';
        }

        return $url;
    }


    /**
     * 提交订单到申通
     *
     * @param array $orderParams
     *  $orderParams = [
     *      // 发件人信息
     *      'SenderName' => 'sean',
     *      'SenderMobile' => '15162696993',
     *      'SenderProvince' => '江苏省',
     *      'SenderCity' => '连云港市',
     *      'SenderDistrict' => '东海县',
     *      'SenderTown' => '',
     *      'SenderAddress' => '东海第二中学',
     *
     *      // 收件人信息
     *      'ReceiverName' => 'chen',
     *      'ReceiverMobile' => '15162698888',
     *      'ReceiverProvince' => '上海',
     *      'ReceiverCity' => '上海市',
     *      'ReceiverDistrict' => '宝山区',
     *      'ReceiverTown' => '',
     *      'ReceiverAddress' => '长逸路188号',
     *
     *      // 物品信息
     *      'GoodsType' => '物品',    // 物品类型（默认：物品、文件）
     *      'GoodsName' => '',    // 物品名称
     *  ];
     * @return array
     */
    public function add(array $orderParams)
    {
        // 数据验证
        if (!$orderParams['SenderMobile']) {
            return [
                'status' => false,
                'msg' => '发件人手机必填',
                'data' => ''
            ];
        }

        $reqParams = $this->getReqParams('sto.order.add', $orderParams);

        // 成功 {"Status":true,"ResultValue":"ST201703011515009720826","StatusCode":"OK","StatusMessage":"下单到梧桐成功","RecordCount":1}
        // 失败 {"Status":false,"ResultValue":"","StatusCode":"OK","StatusMessage":"发件人手机不能为空。","RecordCount":0}
        $response = json_decode($this->request($this->getApi(), $reqParams), true);
        if (!is_array($response) || $response['Status'] == false) {
            logError($response, 'sto-api-add', '申通接口下单失败');
            return [
                'status' => false,
                'msg' => $response['StatusMessage'],
                'data' => $response['ResultValue']
            ];
        }

        return [
            'status' => true,
            'msg' => $response['StatusMessage'],
            'data' => $response['ResultValue']
        ];
    }

    /**
     * 用户取消订单
     *
     * @param array $orderParams
     * $orderParams = [
     *      'OrderIdList' => ['ST201703021041137249442'],
     *      'Reason' => '客户取消订单',
     *  ];
     * @return array
     */
    public function cancel(array $orderParams)
    {
        $reqParams = $this->getReqParams('sto.order.cancel', $orderParams);

        // 成功 {"Status":true,"ResultValue":"","StatusCode":"OK","StatusMessage":"取消成功1条，失败0条，重复取消0条。","RecordCount":1}
        // 失败 {"Status":false,"ResultValue":"","StatusCode":"OK","StatusMessage":"请勿重复取消，失败1条。","RecordCount":0}
        $response = json_decode($this->request($this->getApi(), $reqParams), true);
        if (!is_array($response) || $response['Status'] == false) {
            logError($response, 'sto-feedback-cancel', '申通接口取消订单失败');
            return [
                'status' => false,
                'msg' => $response['StatusMessage'],
                'data' => $response['ResultValue']
            ];
        }

        return [
            'status' => true,
            'msg' => $response['StatusMessage'],
            'data' => $response['ResultValue']
        ];
    }

    /**
     * 业务员取消订单
     * @param array $orderParams
     * $orderParams = [
     *   {
     *      "OrderId":"ST201705171634342831630",
     *      "Reason":1,
     *      "UserCode":"9000000070",
     *      "UserMobile":"13661964640"
     *   }
     *   ];
     * @return array
     */
    public function courierCancel(array $orderParams)
    {
        $reqParams = $this->getReqParams('sto.order.return', $orderParams);

        // 成功 {"Status":true,"ResultValue":"","StatusCode":"OK","StatusMessage":"取消成功1条，失败0条，重复取消0条。","RecordCount":1}
        // 失败 {"Status":false,"ResultValue":"","StatusCode":"OK","StatusMessage":"请勿重复取消，失败1条。","RecordCount":0}
        $response = json_decode($this->request($this->getApi(), $reqParams), true);
        if (!is_array($response) || $response['Status'] == false) {
            logDebug($response,'sto.order.return', '申通快递员取消订单接口失败');
            return [
                'status' => false,
                'msg'    => $response['StatusMessage'],
                'data'   => json_decode($response['ResultValue'], true)
            ];
        }

        return [
            'status' => true,
            'msg'    => $response['StatusMessage'],
            'data'   => json_decode($response['ResultValue'], true)
        ];
    }

    /**
     * 用户绑定运单号
     *
     * @param array $orderParams
     * $orderParams = [
     *      'OrderId' => 'ST201703021041137249442',
     *      'BillCode' => '221088308940',
     *  ];
     * @return array
     */
    public function bindBillCode(array $orderParams)
    {
        $reqParams = $this->getReqParams('sto.order.bindbillcode', $orderParams);

        // 成功 {"Status":true,"ResultValue":"","StatusCode":"OK","StatusMessage":"绑单成功","RecordCount":0}
        // 失败 {"Status":false,"ResultValue":"","StatusCode":"OK","StatusMessage":"此订单已绑定单号","RecordCount":0}
        $response = json_decode($this->request($this->getApi(), $reqParams), true);
        if (!is_array($response) || $response['Status'] == false) {
            logDebug('orderParams-'.json_encode($orderParams,JSON_UNESCAPED_UNICODE).'--response-'.json_encode($response,JSON_UNESCAPED_UNICODE), 'sto-feedback-bindBillCode', '申通绑定运单号接口失败',true);
            return [
                'status' => false,
                'msg' => $response['StatusMessage'],
                'data' => $response['ResultValue']
            ];
        }

        return [
            'status' => true,
            'msg' => $response['StatusMessage'],
            'data' => $response['ResultValue']
        ];
    }

    /**
     * 获取请求包体
     *
     * @param $funcName 请求方法 如：sto.order.add
     * @param array $funcParams 请求参数
     * @return array
     */
    private function getReqParams($funcName, array $funcParams)
    {
        $content = base64_encode(json_encode($funcParams));
        $timeSpan = date('Y-m-d H:i:s');
        $verify = md5($this->appKey . $timeSpan . $content . $this->appSecret);

        $reqParams = [
            'RequestType' => 'json',    // 该参数指明请求和返回的数据格式，目前仅支持json，暂不支持xml或csv等其他格式。
            'Func' => $funcName,  // 该参数指明需要请求的功能，具体请参考各项接口说明。
            'Content' => $content,        // 数据内容，需要进行BASE64编码
            'AppKey' => $this->appKey,
            'TimeSpan' => $timeSpan,    // 日期为24小时制的请求接口时的时间，格式为：“2017-2-21 22:20:38”
            'Signature' => $verify,        // 数据效验码，用于效验数据是否正确完整
            'Version' => '1.0',
        ];
        return $reqParams;
    }


    protected function request($url, array $params)
    {
        return http::post($url, json_encode($params), [
            'TIMEOUT' => 100
//            'HTTPHEADER' => ['charset=utf-8']
//            'HTTPHEADER' => ['Content-type:application/raw; charset=utf-8']
//            'HTTPHEADER' => ['Content-type:application/x-www-form-urlencoded; charset=utf-8']
//            'HTTPHEADER' => ['Content-type:application/json; charset=utf-8']
        ]);
    }


}